package net.ikenway.springboot.demo.Model.Entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.lang.Nullable;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.persistence.*;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author MasterKenway <zk@ikenway.net>
 * @Description
 * @date Created Date 12/9/2020
 */
@Entity
@DynamicUpdate
@Data
@Table(name = "users", uniqueConstraints=@UniqueConstraint(columnNames={"username"}))
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable, UserDetails {
    public enum Identity {
        CUSTOMER,
        MANAGER,
        ROOT
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long userId;

    private String avatar = null;

    @Size(min = 2, max = 50)
    private String name;

    @Column(nullable = false, unique = true)
    private String username;


    @Column(nullable = false)
    private String password;

    @Enumerated(EnumType.STRING)
    private Identity identity = Identity.CUSTOMER;

    @OneToMany(targetEntity = Address.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    @Nullable
    private List<Address> address = null;

    @OneToMany(targetEntity = Order.class, cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private List<Order> orders = null;

    private Boolean enabled = true;

    private Boolean accountNonExpired = true;

    private Boolean accountNonLocked = true;

    private boolean credentialsNonExpired = true;

    public User(String username) {
        this.username = username;
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }


    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Collection<GrantedAuthority> authorityCollection = new ArrayList<>();
        switch (this.getIdentity()) {
            case CUSTOMER:
                authorityCollection.add(new SimpleGrantedAuthority("CUSTOMER"));
                break;
            case MANAGER:
                authorityCollection.add(new SimpleGrantedAuthority("MANAGER"));
                break;
            case ROOT:
                authorityCollection.add(new SimpleGrantedAuthority("ROOT"));
                break;
        }
        return authorityCollection;
    }

    @Override
    public boolean isAccountNonExpired() {
        return this.accountNonExpired;
    }

    @Override
    public boolean isAccountNonLocked() {
        return this.accountNonLocked;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return credentialsNonExpired;
    }

    @Override
    public boolean isEnabled() {
        return this.enabled;
    }
}
